const express = require('express');
const { Op } = require('sequelize');
const { body, query, param, validationResult } = require('express-validator');
const db = require('../models');
const logger = require('../utils/logger');
const sequelize = require('sequelize');

const router = express.Router();
const { Tag, Lesson } = db;

// 验证中间件
const handleValidation = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({
      error: '请求参数验证失败',
      details: errors.array()
    });
  }
  next();
};

// 获取标签列表
router.get('/', [
  query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
  query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
  query('isActive').optional().isBoolean().withMessage('激活状态必须是布尔值'),
  query('search').optional().isLength({ min: 1 }).withMessage('搜索关键词不能为空'),
  query('orderBy').optional().isIn(['name', 'usageCount', 'createdAt']).withMessage('排序字段无效'),
  query('order').optional().isIn(['ASC', 'DESC']).withMessage('排序方向无效'),
  handleValidation
], async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 50;
    const offset = (page - 1) * limit;
    const { isActive, search, orderBy = 'usageCount', order = 'DESC' } = req.query;

    // 构建查询条件
    const where = {};
    
    if (isActive !== undefined) {
      where.isActive = isActive === 'true';
    }
    
    if (search) {
      where[Op.or] = [
        { name: { [Op.like]: `%${search}%` } },
        { description: { [Op.like]: `%${search}%` } }
      ];
    }

    const { count, rows } = await Tag.findAndCountAll({
      where,
      order: [[orderBy, order]],
      limit,
      offset,
      attributes: {
        include: [
          [
            sequelize.literal(`(
              SELECT COUNT(*) 
              FROM lesson_tags 
              WHERE lesson_tags.tag_id = Tag.id
            )`),
            'lessonCount'
          ]
        ]
      }
    });

    res.json({
      data: rows,
      pagination: {
        page,
        limit,
        total: count,
        pages: Math.ceil(count / limit)
      }
    });

  } catch (error) {
    logger.error('获取标签列表失败:', error);
    res.status(500).json({ error: '获取标签列表失败' });
  }
});

// 获取标签统计信息
router.get('/stats', async (req, res) => {
  try {
    const stats = await Tag.findAll({
      attributes: [
        'isActive',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('usage_count')), 'totalUsage']
      ],
      group: ['isActive']
    });

    const totalTags = await Tag.count();
    const activeTags = await Tag.count({ where: { isActive: true } });
    const inactiveTags = await Tag.count({ where: { isActive: false } });

    res.json({
      data: {
        total: totalTags,
        active: activeTags,
        inactive: inactiveTags,
        usageStats: stats
      }
    });

  } catch (error) {
    logger.error('获取标签统计失败:', error);
    res.status(500).json({ error: '获取标签统计失败' });
  }
});

// 获取热门标签
router.get('/popular', [
  query('limit').optional().isInt({ min: 1, max: 50 }).withMessage('数量必须在1-50之间'),
  handleValidation
], async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 20;

    const tags = await Tag.findAll({
      where: { 
        isActive: true,
        usageCount: { [Op.gt]: 0 }
      },
      order: [['usageCount', 'DESC']],
      limit,
      attributes: {
        include: [
          [
            sequelize.literal(`(
              SELECT COUNT(*) 
              FROM lesson_tags 
              WHERE lesson_tags.tag_id = Tag.id
            )`),
            'lessonCount'
          ]
        ]
      }
    });

    res.json({ data: tags });

  } catch (error) {
    logger.error('获取热门标签失败:', error);
    res.status(500).json({ error: '获取热门标签失败' });
  }
});

// 根据ID获取标签详情
router.get('/:id', [
  param('id').isInt().withMessage('标签ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const tag = await Tag.findByPk(req.params.id, {
      include: [
        {
          model: Lesson,
          as: 'lessons',
          attributes: ['id', 'title', 'slug', 'excerpt', 'difficulty', 'duration', 'isPublished'],
          where: { isPublished: true },
          required: false,
          through: { attributes: [] },
          order: [['createdAt', 'DESC']]
        }
      ],
      attributes: {
        include: [
          [
            sequelize.literal(`(
              SELECT COUNT(*) 
              FROM lesson_tags 
              WHERE lesson_tags.tag_id = Tag.id
            )`),
            'lessonCount'
          ]
        ]
      }
    });

    if (!tag) {
      return res.status(404).json({ error: '标签不存在' });
    }

    res.json({ data: tag });

  } catch (error) {
    logger.error('获取标签详情失败:', error);
    res.status(500).json({ error: '获取标签详情失败' });
  }
});

// 根据slug获取标签详情
router.get('/slug/:slug', [
  param('slug').isLength({ min: 1 }).withMessage('标签标识不能为空'),
  handleValidation
], async (req, res) => {
  try {
    const tag = await Tag.findOne({
      where: { slug: req.params.slug },
      include: [
        {
          model: Lesson,
          as: 'lessons',
          attributes: ['id', 'title', 'slug', 'excerpt', 'difficulty', 'duration', 'isPublished'],
          where: { isPublished: true },
          required: false,
          through: { attributes: [] },
          order: [['createdAt', 'DESC']]
        }
      ],
      attributes: {
        include: [
          [
            sequelize.literal(`(
              SELECT COUNT(*) 
              FROM lesson_tags 
              WHERE lesson_tags.tag_id = Tag.id
            )`),
            'lessonCount'
          ]
        ]
      }
    });

    if (!tag) {
      return res.status(404).json({ error: '标签不存在' });
    }

    res.json({ data: tag });

  } catch (error) {
    logger.error('获取标签详情失败:', error);
    res.status(500).json({ error: '获取标签详情失败' });
  }
});

// 创建标签
router.post('/', [
  body('name').notEmpty().withMessage('标签名称不能为空'),
  body('slug').notEmpty().withMessage('标签标识不能为空'),
  body('color').optional().matches(/^#[0-9A-Fa-f]{6}$/).withMessage('颜色格式不正确'),
  body('description').optional().isLength({ max: 255 }).withMessage('描述不能超过255字符'),
  body('isActive').optional().isBoolean().withMessage('激活状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    const tag = await Tag.create(req.body);
    logger.info(`创建标签成功: ${tag.name} (ID: ${tag.id})`);
    
    res.status(201).json({
      message: '标签创建成功',
      data: tag
    });

  } catch (error) {
    logger.error('创建标签失败:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '标签名称或标识已存在' });
    }
    
    res.status(500).json({ error: '创建标签失败' });
  }
});

// 批量创建标签
router.post('/batch', [
  body('tags').isArray().withMessage('标签数据必须是数组'),
  body('tags.*.name').notEmpty().withMessage('标签名称不能为空'),
  body('tags.*.slug').notEmpty().withMessage('标签标识不能为空'),
  body('tags.*.color').optional().matches(/^#[0-9A-Fa-f]{6}$/).withMessage('颜色格式不正确'),
  body('tags.*.description').optional().isLength({ max: 255 }).withMessage('描述不能超过255字符'),
  body('tags.*.isActive').optional().isBoolean().withMessage('激活状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    const tags = await Tag.bulkCreate(req.body.tags, {
      validate: true,
      returning: true
    });
    
    logger.info(`批量创建标签成功: ${tags.length} 个标签`);
    
    res.status(201).json({
      message: '批量创建标签成功',
      data: tags
    });

  } catch (error) {
    logger.error('批量创建标签失败:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '存在重复的标签名称或标识' });
    }
    
    res.status(500).json({ error: '批量创建标签失败' });
  }
});

// 更新标签
router.put('/:id', [
  param('id').isInt().withMessage('标签ID必须是整数'),
  body('name').optional().notEmpty().withMessage('标签名称不能为空'),
  body('slug').optional().notEmpty().withMessage('标签标识不能为空'),
  body('color').optional().matches(/^#[0-9A-Fa-f]{6}$/).withMessage('颜色格式不正确'),
  body('description').optional().isLength({ max: 255 }).withMessage('描述不能超过255字符'),
  body('isActive').optional().isBoolean().withMessage('激活状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    const tag = await Tag.findByPk(req.params.id);
    
    if (!tag) {
      return res.status(404).json({ error: '标签不存在' });
    }

    await tag.update(req.body);
    logger.info(`更新标签成功: ${tag.name} (ID: ${tag.id})`);
    
    res.json({
      message: '标签更新成功',
      data: tag
    });

  } catch (error) {
    logger.error('更新标签失败:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '标签名称或标识已存在' });
    }
    
    res.status(500).json({ error: '更新标签失败' });
  }
});

// 批量更新标签
router.put('/batch', [
  body('tags').isArray().withMessage('标签数据必须是数组'),
  body('tags.*.id').isInt().withMessage('标签ID必须是整数'),
  body('tags.*.name').optional().notEmpty().withMessage('标签名称不能为空'),
  body('tags.*.slug').optional().notEmpty().withMessage('标签标识不能为空'),
  body('tags.*.color').optional().matches(/^#[0-9A-Fa-f]{6}$/).withMessage('颜色格式不正确'),
  body('tags.*.description').optional().isLength({ max: 255 }).withMessage('描述不能超过255字符'),
  body('tags.*.isActive').optional().isBoolean().withMessage('激活状态必须是布尔值'),
  handleValidation
], async (req, res) => {
  try {
    const updates = req.body.tags.map(tag => ({
      ...tag,
      updatedAt: new Date()
    }));

    await Tag.bulkCreate(updates, {
      updateOnDuplicate: ['name', 'slug', 'color', 'description', 'isActive', 'updatedAt']
    });
    
    logger.info(`批量更新标签成功: ${updates.length} 个标签`);
    
    res.json({
      message: '批量更新标签成功',
      data: updates
    });

  } catch (error) {
    logger.error('批量更新标签失败:', error);
    
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({ error: '存在重复的标签名称或标识' });
    }
    
    res.status(500).json({ error: '批量更新标签失败' });
  }
});

// 删除标签
router.delete('/:id', [
  param('id').isInt().withMessage('标签ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const tag = await Tag.findByPk(req.params.id);
    
    if (!tag) {
      return res.status(404).json({ error: '标签不存在' });
    }

    // 检查是否有关联的课程
    const lessonCount = await Lesson.count({
      include: [{
        model: Tag,
        as: 'tags',
        where: { id: req.params.id },
        through: { attributes: [] }
      }]
    });
    
    if (lessonCount > 0) {
      return res.status(400).json({ 
        error: '存在关联的课程，无法删除',
        lessonCount 
      });
    }

    await tag.destroy();
    logger.info(`删除标签成功: ${tag.name} (ID: ${tag.id})`);
    
    res.json({ message: '标签删除成功' });

  } catch (error) {
    logger.error('删除标签失败:', error);
    res.status(500).json({ error: '删除标签失败' });
  }
});

// 批量删除标签
router.delete('/batch', [
  body('ids').isArray().withMessage('标签ID列表必须是数组'),
  body('ids.*').isInt().withMessage('标签ID必须是整数'),
  handleValidation
], async (req, res) => {
  try {
    const { ids } = req.body;

    // 检查是否有关联的课程
    const lessonCounts = await Lesson.findAll({
      include: [{
        model: Tag,
        as: 'tags',
        where: { id: { [Op.in]: ids } },
        through: { attributes: [] }
      }],
      attributes: [
        'id',
        [sequelize.fn('COUNT', sequelize.col('lessons.id')), 'count']
      ],
      group: ['lessons.id']
    });

    if (lessonCounts.some(count => count.get('count') > 0)) {
      return res.status(400).json({ 
        error: '存在关联的课程，无法删除',
        lessonCounts: lessonCounts.map(count => ({
          id: count.id,
          count: count.get('count')
        }))
      });
    }

    await Tag.destroy({
      where: { id: { [Op.in]: ids } }
    });
    
    logger.info(`批量删除标签成功: ${ids.length} 个标签`);
    
    res.json({ message: '批量删除标签成功' });

  } catch (error) {
    logger.error('批量删除标签失败:', error);
    res.status(500).json({ error: '批量删除标签失败' });
  }
});

module.exports = router; 